﻿
#if !(UNITY_STANDALONE_WIN || UNITY_STANDALONE_LINUX || UNITY_STANDALONE_OSX || STEAMWORKS_WIN || STEAMWORKS_LIN_OSX)
#define DISABLESTEAMWORKS
#endif
#if !DISABLESTEAMWORKS
using Steamworks;
#endif
using System;
using System.Collections;
using System.Collections.Generic;
using System.Net;
using UnityEngine;
using Mirror;



public class RobbyPanel : MonoBehaviour
{
    public SceneSwiter m_SceneSwiter;
    public GameObject m_List;
    public RobbyPanelItem m_RobbyItemPerfab;

    public RoomListFindout m_FindoutDiscovery;
    public GameObject m_ConnectingPanel;
    readonly Dictionary<int, RobbyPanelItem> discoveredServers = new Dictionary<int, RobbyPanelItem>();

#if !DISABLESTEAMWORKS
    public Callback<LobbyCreated_t> OnSteamLobbyCreatedCallback;
    public Callback<LobbyEnter_t> OnSteamLobbyJointedCallback;
#endif
    private void Awake()
    {
        m_FindoutDiscovery = OnlineManager.singleton.GetComponent<RoomListFindout>();
        m_FindoutDiscovery.OnServerFound.AddListener(OnDiscoveredServer);
        if(!UtilsGame.IsSteamMG())
        {
            (OnlineManager.singleton as OnlineManager).OnClientConnectCallback = OnClientConnect;
            (OnlineManager.singleton as OnlineManager).OnServerConnectCallback = OnServerConnect;
            (OnlineManager.singleton as OnlineManager).OnClientStopedCallback = OnClientStopConnect;
            (OnlineManager.singleton as OnlineManager).OnHostStopedCallback = OnHostStopConnect;
        }
    }

    void Start()
    {

#if !DISABLESTEAMWORKS
        if (UtilsGame.IsSteamMG())
        {
            OnSteamLobbyCreatedCallback = Callback<LobbyCreated_t>.Create(OnSteamLobbyCreated);
            OnSteamLobbyJointedCallback = Callback<LobbyEnter_t>.Create(OnSteamLobbyJointed);
        }
#endif
    }
    private void OnEnable()
    {
        OnRefreshClicked();
    }

    // Update is called once per frame
    void Update()
    {
        //foreach (var info in discoveredServers.Values)
        //    if (GUILayout.Button(info.)
        //        Connect(info);

    }
    private void OnDestroy()
    {
        m_FindoutDiscovery.OnServerFound.RemoveListener(OnDiscoveredServer);
    }
#if !DISABLESTEAMWORKS
    //DiscoveryResponse
    CallResult<LobbyMatchList_t> m_CallResultLobbyMatchList = new CallResult<LobbyMatchList_t>();
#endif
    public void OnRefreshClicked()
    {
        foreach(var item in discoveredServers)
        {
            Destroy(item.Value.gameObject);
        }
        discoveredServers.Clear();

#if !DISABLESTEAMWORKS
        if(UtilsGame.IsSteamMG())
        {
            // SteamMatchmaking()->AddRequestLobbyListFilter*() 函数会在此调用，先于 RequestLobbyList()
            SteamAPICall_t hSteamAPICall = SteamMatchmaking.RequestLobbyList();
            m_CallResultLobbyMatchList.Set(hSteamAPICall, OnLobbyMatchList);
        }
#endif
        if (!UtilsGame.IsSteamMG())
        {
            m_FindoutDiscovery.StartDiscovery();
        }
    }
#if !DISABLESTEAMWORKS
    void OnLobbyMatchList(LobbyMatchList_t pLobbyMatchList, bool bIOFailure)
    {
        var numLobby = pLobbyMatchList.m_nLobbiesMatching;
        for (int i=0; i< numLobby; ++i)
        {
            var lobbyId = SteamMatchmaking.GetLobbyByIndex(i);
            if (lobbyId.IsValid() == false)
                continue;
            int numPlayer = SteamMatchmaking.GetNumLobbyMembers(lobbyId);
            var responsee = new DiscoveryResponse();

            var serverIDS = SteamMatchmaking.GetLobbyData(lobbyId, "ServerID");
            if (serverIDS != "")
                responsee.serverId = int.Parse(serverIDS);

            responsee.steamId = lobbyId.m_SteamID;

            responsee.name = SteamMatchmaking.GetLobbyData(lobbyId, "Name");

            var numPlayerMaxS = SteamMatchmaking.GetLobbyData(lobbyId, "MaxPlayerNumber");
            if(numPlayerMaxS!= "")
            responsee.numPlayersMax = int.Parse(numPlayerMaxS);

            responsee.numPlayers = numPlayer;

            var isPlayingS = SteamMatchmaking.GetLobbyData(lobbyId, "IsPlaying");
            if (isPlayingS != "")
                responsee.isPlaying = bool.Parse(isPlayingS);
            OnDiscoveredServer(responsee);
        }

    }
#endif
    public void OnCreateRoomClicked()
    {
#if !DISABLESTEAMWORKS
        if (UtilsGame.IsSteamMG())
        {
            if (m_ConnectingPanel)
                m_ConnectingPanel.gameObject.SetActive(true);
            SteamMatchmaking.CreateLobby(ELobbyType.k_ELobbyTypePublic, OnlineManager.singleton.maxConnections);
        }
#else
#endif
        if (!UtilsGame.IsSteamMG())
        {
            m_FindoutDiscovery.StopDiscovery();
            if (m_ConnectingPanel)
                m_ConnectingPanel.gameObject.SetActive(true);
            try
            {
                OnlineManager.singleton.StartHost();
            }
            catch
            {
                if (m_ConnectingPanel)
                    m_ConnectingPanel.gameObject.SetActive(false);
                MessageShow.Instance.Messaage("创建失败，我也不知道为啥！", new Vector4(1,0,0,1));
            }
            m_FindoutDiscovery.roomName = Commander.Instance.m_Name + "'s room";
            m_FindoutDiscovery.AdvertiseServer();
        }
    }
#if !DISABLESTEAMWORKS
    void OnSteamLobbyCreated(LobbyCreated_t callbackValue)
    {
        if (callbackValue.m_eResult != EResult.k_EResultOK)
        {
            MessageShow.Instance.Messaage("创建房间失败！");
            if (m_ConnectingPanel)
                m_ConnectingPanel.gameObject.SetActive(false);
            return;
        }

        discoveredServers.Clear();
        int serverID = UnityEngine.Random.Range(int.MinValue, int.MaxValue);
        SteamMatchmaking.SetLobbyData(new CSteamID(callbackValue.m_ulSteamIDLobby), "ServerID",
            serverID.ToString());
        SteamMatchmaking.SetLobbyData(new CSteamID(callbackValue.m_ulSteamIDLobby),"HostAddress",
            SteamUser.GetSteamID().ToString());

        SteamMatchmaking.SetLobbyData(new CSteamID(callbackValue.m_ulSteamIDLobby), "Name",
            Commander.Instance.m_Name + "'s room");

        SteamMatchmaking.SetLobbyData(new CSteamID(callbackValue.m_ulSteamIDLobby), "MaxPlayerNumber",
            OnlineManager.singleton.maxConnections.ToString());
        SteamMatchmaking.SetLobbyData(new CSteamID(callbackValue.m_ulSteamIDLobby), "IsPlaying",
            false.ToString());
        //SteamMatchmaking.SetLobbyData(new CSteamID(callbackValue.m_ulSteamIDLobby), "CurrentPlayerNumber",
        //    OnlineManager.singleton.numPlayers.ToString());

        OnlineManager.singleton.networkAddress = SteamUser.GetSteamID().ToString();
        (OnlineManager.singleton as OnlineManager).m_LobbyId = new CSteamID(callbackValue.m_ulSteamIDLobby);
        OnlineManager.singleton.StartHost();
    }
    void OnSteamLobbyJointed(LobbyEnter_t callbackValue)
    {
        if(callbackValue.m_EChatRoomEnterResponse == (ulong)EChatRoomEnterResponse.k_EChatRoomEnterResponseError)
        {
            MessageShow.Instance.Messaage("Steam: 无法加入房间，或许房间已经失效，刷新一下或者检查Steam的连接状态再试试看。");
            if(m_ConnectingPanel)
            m_ConnectingPanel.gameObject.SetActive(false);
            return;
        }
        if (NetworkServer.active)
            return;
        var steamUserId  = SteamMatchmaking.GetLobbyData(new CSteamID(callbackValue.m_ulSteamIDLobby), "HostAddress");
        (OnlineManager.singleton as OnlineManager).m_LobbyId = new CSteamID(callbackValue.m_ulSteamIDLobby);
        OnlineManager.singleton.networkAddress = steamUserId;
        OnlineManager.singleton.StartClient();
    }
#endif

    public void OnDiscoveredServer(DiscoveryResponse info)
    {
        if(info.isPlaying == true)
        {
            if (discoveredServers.ContainsKey(info.serverId))
                discoveredServers[info.serverId].gameObject.SetActive(false);
            return;
        }
        RobbyPanelItem item = null;
        if (!discoveredServers.ContainsKey(info.serverId))
        {
            var itemObj = Instantiate(m_RobbyItemPerfab);
            itemObj.transform.SetParent(m_List.transform);
            itemObj.transform.localScale = new Vector3(1, 1, 1);
            item = itemObj.GetComponent<RobbyPanelItem>();
            item.OnJoint = OnConnectClicked;
            discoveredServers[info.serverId] = item;
        }

        item = discoveredServers[info.serverId];
        if(item.gameObject.activeSelf == false)
            item.gameObject.SetActive(true);
        item.Info = info;
    }

    public void OnConnectClicked(DiscoveryResponse info)
    {
        //uri.Host;
#if !DISABLESTEAMWORKS
        if (UtilsGame.IsSteamMG())
        {
            if (info.steamId == 0 ||
            new CSteamID(info.steamId).IsValid() == false)
            {
                MessageShow.Instance.Messaage("无法加入房间，或许房间已经失效，刷新一下再试试看。");
                return;
            }
            SteamMatchmaking.JoinLobby(new CSteamID(info.steamId));
        }
#endif
        if (!UtilsGame.IsSteamMG())
        {
            Debug.Log("joint host : " + info.host);
            OnlineManager.singleton.networkAddress = info.host;
            OnlineManager.singleton.StartClient();
        }
        if (m_ConnectingPanel)
            m_ConnectingPanel.gameObject.SetActive(true);
    }

    void OnClientConnect()
    {
        if(m_ConnectingPanel)
            m_ConnectingPanel.gameObject.SetActive(false);
    }
    void OnServerConnect()
    {
        if(m_ConnectingPanel)
            m_ConnectingPanel.gameObject.SetActive(false);
    }
    void OnClientStopConnect()
    {
        if(m_ConnectingPanel)
            m_ConnectingPanel.gameObject.SetActive(false);
    }
    void OnHostStopConnect()
    {
        if(m_ConnectingPanel)
            m_ConnectingPanel.gameObject.SetActive(false);
    }

    public void OnEnabledClicked()
    {
        if (!UtilsGame.CheckSelectShip())
            return;
        if (!UtilsGame.IsOnline())
        {
            gameObject.SetActive(true);
        }
        else
        {
            m_SceneSwiter.switchScene(OnlineManager.singleton.onlineScene);
        }
    }
    
}
